#============================================================
# Create Time:			2021-10-19 08:06:18
# Last modify:			2021-11-02 09:14:10
# Writer:				Wenhao	wh.wenhao@foxmail.com
# File Name:			parse.py
# File Type:			PY Source File
# Tool:					Mac -- vim & python
# Information:			
#============================================================
import os
import argparse

class GPSInfo:
    def __init__(this, data_tuple:str):
        this.fields = [item.strip() for item in data_tuple.split(',')]

    def data_formated(this):...

    @staticmethod
    def _get_height(height_str):
        '''
        @createTime: 2021-10-26 05:59:41
        @arg: height_str : 天线离海平面的高度	-9999.9~9999.9米
        @rtn: 
        '''
        return '%s米'%(height_str)

    @staticmethod
    def _get_direction_angle(angle_str):
        '''
        @createTime: 2021-10-26 05:59:20
        @arg: angle_str: 方位角	度（以真北为参考基准）
        @rtn: 
        '''
        dir_angle = float(angle_str)
        return '北%.0f度%.0f分'%(dir_angle, (dir_angle - int(dir_angle)) * 60)

    @staticmethod
    def _get_date(date_str):
        """
        @createTime: 2021-10-26 06:00:38
        @arg: date_str: 字段9	UTC日期	日月年，ddmmyy
        @rtn: 
        """
        day, month, year = date_str[0:2], date_str[2:4], date_str[4:6]
        return '20%s年%s月%s日'%(year, month, day)

    @staticmethod
    def _get_time(time_str):
        """
        @createTime: 2021-10-26 06:00:44
        @arg: time_str: 字段9	UTC日期	日月年，ddmmyy
        @rtn: 
        """
        hour = time_str[:2]
        minute = time_str[2:4]
        seconds = time_str[4:6]
        return '%s时%s分%s秒'%(hour, minute, seconds)

    @staticmethod
    def _get_gps_pos(longitude, latitude, east, north):
        """
        @createTime: 2021-10-26 06:00:52
        @arg: longitude 字段5	经度	dddmm.mmmm
        @arg:  latitude 字段3	纬度	ddmm.mmmm
        @arg:  east 字段6	东经/西经	E/W，E表示东经，W表示西经
        @arg:  north 字段4	北纬/南纬	N/S，N表示北纬，S表示南纬
        @rtn: 
        """
        # 处理位置
        pos = '%s%s度%s分%s秒，%s%s度%s分%s秒'%(
            #'东经' if this.fields[6] == 'E' else '西经',
            '东经' if east == 'E' else '西经',
            longitude[:3],
            longitude[3:5],
            '%2d'%(float(longitude[-5:]) * 60),

            #'北纬' if this.fields[4] == 'N' else '南纬',
            '北纬' if north == 'N' else '南纬',
            latitude[:2],
            latitude[2:4],
            '%2d'%(float(latitude[-5:]) * 60),
        )
        return pos

    @staticmethod
    def _get_speed(speed_str, knots=False):
        """
        @createTime: 2021-10-26 06:01:03
        @arg: speed_str 字段7	速度	节(knots)，1 knots=1.852km/h
        @arg:  knots=False 
        @rtn: 
        """
        factor = 1.852 if knots else 1
        speed = float(speed_str)
        speed *= factor
        return '%.1f公里/小时'%(speed)

    def __str__(this):
        formated = this.data_formated()
        if formated:
            return formated
        return ''


class GPRMC(GPSInfo):
    '''GPRMC	Recommended Minimum Specific GPS/TRANSIT Data（RMC）	推荐定位信息
        字段0	帧头	$GPRMC
        字段1	UTC时间	hhmmss.ss
        字段2	状态	A/V,A代表有效，V代表无效
        字段3	纬度	ddmm.mmmm
        字段4	北纬/南纬	N/S，N表示北纬，S表示南纬
        字段5	经度	dddmm.mmmm
        字段6	东经/西经	E/W，E表示东经，W表示西经
        字段7	速度	节(knots)，1 knots=1.852km/h
        字段8	方位角	度（以真北为参考基准）
        字段9	UTC日期	日月年，ddmmyy
        字段10	磁偏角	000~180度
        字段11	磁偏角方向	E/W，东/西
        字段12	模式仅NMEA0183 3.00版本输出	A:自动，D:差分，E:估测，N:无效
        字段13	校验值	hh
        '''

    def data_formated(this):
        if this.fields[2] == 'V':
            return '无效！'
        # 处理时间
        date_info = this.get_date()
        time_info = this.get_time()
        time = '%s，%s'%(date_info, time_info)

        # 处理位置
        pos = this.get_gps_pos()

        # 处理方向
        direction = this.get_direction_angle()

        # 处理航速
        speed = this.get_speed()

        return f'''时间：{time}
位置：{pos}
方向：{direction}
航速：{speed}
'''
    def get_date(this):
        return GPSInfo._get_date(date_str=this.fields[9])

    def get_time(this):
        return GPSInfo._get_time(time_str=this.fields[1])

    def get_gps_pos(this):
        return GPSInfo._get_gps_pos(
            longitude=this.fields[5],
            latitude=this.fields[3],
            east=this.fields[6],
            north=this.fields[4]
        )

    def get_direction_angle(this):
        return GPSInfo._get_direction_angle(angle_str=this.fields[8])

    def get_speed(this):
        return GPSInfo._get_speed(speed_str=this.fields[7], knots=True)


class GPGGA(GPSInfo):
    '''GPGGA	Global Positioning System Fix Data（GGA）	全球定位信息
        字段0	帧头	$GPGGA
        字段1	UTC时间	Hhmmss.sss
        字段2	纬度	ddmm.mmmm
        字段3	北纬/南纬	N/S
        字段4	经度	dddmm.mmmm
        字段5	东经/西经	E/W
        字段6	定位质量指标	0：定位无效，1：实时GPS，2：差分GPS
        字段7	使用卫星数量	00~12
        字段8	水平精度	0.5~99.9
        字段9	天线离海平面的高度	-9999.9~9999.9米
        字段10	高度单位	通常为M：米
        字段11	大地椭球面相对海平面的高度	-999.9~9999.9
        字段12	高度单位	通常为M：米
        字段13	差分GPS数据期限
        字段14	差分参考基站标号	0000~1023
        字段15	hh	校验和
        '''

    def get_height(this):
        return GPSInfo._get_height(height_str=this.fields[9])

class GPVTG(GPSInfo):
    '''GPVTG	Track Made Good and Ground Speed（VTG）	地面速度信息
        字段0	$GPVTG	表示GPS信息类型为GPVTG
        字段1	0.0	地面速度
        字段2	T	航向标志位，真北方向
        字段3	无	地面速度
        字段4	M	航向标志位，磁北方向
        字段5	0.00	水平运动速度
        字段6	N	单位：节
        字段7	0.00	水平运动速度
        字段8	K	单位：km/h
        字段9	N	无效
        字段10	50	校验和
        '''

class GPGSA(GPSInfo):
    '''GPGSA	GPS DOP and Active Satellites（GSA）	当前卫星信息
        字段0	帧头	$GPGGA
        字段1	模式	M:手动，A：自动
        字段2	定位型式	1：未定位，2：二维定位，3：三维定位
        字段3	第1信道正在使用的卫星RPN码编号	Pseudo Random Noise,伪随机噪声码，01~32表示天空中使用的卫星编号，最多可接收12颗卫星信息
        字段4	第2信道正在使用的卫星RPN码编号
        字段5	第3信道正在使用的卫星RPN码编号
        字段6	第4信道正在使用的卫星RPN码编号
        字段7	第5信道正在使用的卫星RPN码编号
        字段8	第6信道正在使用的卫星RPN码编号
        字段9	第7信道正在使用的卫星RPN码编号
        字段10	第8信道正在使用的卫星RPN码编号
        字段11	第9信道正在使用的卫星RPN码编号
        字段12	第10信道正在使用的卫星RPN码编号
        字段13	第11信道正在使用的卫星RPN码编号
        字段14	第12信道正在使用的卫星RPN码编号
        字段15	PDOP综合位置精度因子	0.5~99.9
        字段16	HDOP水平精度因子	0.5~99.9
        字段17	VDOP垂直精度因子	0.5~99.9
        字段18	hh	校验和'''

class GPGSV(GPSInfo):
    '''GPGSV GPS Satellites in View（GSV）	可见卫星信息
        字段0	帧头	$GPGGA
        字段1	总的GSV语句电文数
        字段2	当前GSV语句号
        字段3	可视卫星总数	00~12
        字段4	卫星编号	01~32
        字段5	卫星仰角	00~90度
        字段6	卫星方位角	000~359度
        字段7	信噪比(C/No)	00~99dB,0表示未接收到信号
        字段8	hh	校验和'''

class GPGLL(GPSInfo):
    '''GPGLL	Geographic Position（GLL）	地理定位信息
        字段0	帧头	$GPGLL
        字段1	纬度	ddmm.mmmm
        字段2	北纬/南纬	N/S
        字段3	经度	dddmm.mmmm
        字段4	东经/西经	E/W
        字段5	UTC时间（时分秒）	hhmmss
        字段6	状态标志位	A：有效，V无效
        字段7	hh	校验和'''

def build_args():
    parser = argparse.ArgumentParser()
    parser.add_argument('--file', '-f', type=str, required=True, help='The file to be analysed.')
    args = parser.parse_args()
    return args


if __name__ == '__main__':
    args = build_args()
    assert os.path.exists(args.file), 'The file you are analysing doesn\'t exist!'
    for line in open(args.file, 'r', encoding='utf-8'):
        if line.startswith('$GPGGA'):
            gpgga = GPGGA(line)
            height = '高度：%s'%(gpgga.get_height())
        elif line.startswith('$GPRMC'):
            gprmc = GPRMC(line)
            gps_info = gprmc.data_formated()
            gps_info = '%s%s\n'%(gps_info, height)
            print(gps_info)
